package com.m.system.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.m.system.domain.SysMenuEntity;
import com.m.system.domain.SysRoleEntity;
import com.m.system.domain.TreeSelect;
import com.m.system.mapper.SysMenuMapper;
import com.m.system.service.SysMenuService;
import com.m.utils.IdUtil;
import com.m.utils.UserUtil;

import org.springframework.beans.factory.annotation.Autowired;



/**
 * 菜单权限表Service
 * @author monxz
 * @version 2021-01-29
 */
@Service
@Transactional
public class SysMenuServiceImpl implements SysMenuService{

	@Autowired
	private SysMenuMapper sysMenuMapper;
	
	

	@Override
	public SysMenuEntity findSysMenuById(SysMenuEntity  sysMenuEntity)throws Exception {				
		return sysMenuMapper.get(sysMenuEntity);
	}

	@Override
	public List<SysMenuEntity > findSysMenuList(SysMenuEntity  sysMenuEntity,boolean  needAll)throws Exception {	
		List<SysMenuEntity>  menuList = sysMenuMapper.getList(sysMenuEntity);
		if(needAll) {
			return menuList;
		}
		List<String> roleIds = UserUtil.getUser(null).getRoleList().stream().map(SysRoleEntity::getRoleId).collect(Collectors.toList());		
		List<String>  menuIds = sysMenuMapper.getMenuIdListByRoleIds(roleIds);
		Map<Long, List<SysMenuEntity>>  menuIdMap  = menuList.stream().collect(Collectors.groupingBy(SysMenuEntity::getMenuId));
		List<SysMenuEntity>  res = new ArrayList<>();
		for(String mid : menuIds) {
			if(menuIdMap.get(Long.valueOf(mid)) != null && !menuIdMap.get(Long.valueOf(mid)).isEmpty()) {
				res.addAll(menuIdMap.get(Long.valueOf(mid)) );
			}
		}	
		return res;
	}

	
	@Override
	public Integer addSysMenu(SysMenuEntity  sysMenuEntity)throws Exception {
		sysMenuEntity.setMenuId(Long.valueOf(IdUtil.genId()));
		List<SysRoleEntity> roleList = UserUtil.getUser(null).getRoleList();
		for(SysRoleEntity role : roleList) {
			sysMenuMapper.insertRoleMenu(role.getRoleId(), sysMenuEntity.getMenuId().toString());
		}	
		return sysMenuMapper.insert(sysMenuEntity);
	}

	@Override
	public Integer modifySysMenu(SysMenuEntity  SysMenuEntity)throws Exception {
		return sysMenuMapper.update(SysMenuEntity);
	}

	@Override
	public Integer delete(String menuId)throws Exception {
		sysMenuMapper.deleteRoleMenuByMenuId(menuId);
		return  sysMenuMapper.delete(menuId);
	}

	
	
	@Override
	public Integer checkUnion(SysMenuEntity  SysMenuEntity)throws Exception{
		Long menuId = SysMenuEntity.getMenuId();
		SysMenuEntity.setMenuId(null);
		List<SysMenuEntity>  sysMenuList =  sysMenuMapper.getExctList(SysMenuEntity);
		if( sysMenuList  == null || sysMenuList.isEmpty()){
		 return 0;
		}

		if(menuId!= null && sysMenuList.size() == 1 && menuId == sysMenuList.get(0).getMenuId()) {
			return 0;
		}		
 		return 1;
	}

	@Override
	public List<SysMenuEntity> buildMenuTree(String userId) {
		List<SysMenuEntity> voList = sysMenuMapper.getMenuByRoles(userId); 
		return getChildPerms(voList, 0L);
	}
	
	 /**
     * 根据父节点的ID获取所有子节点
     * 
     * @param list 分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
    public List<SysMenuEntity> getChildPerms(List<SysMenuEntity> list, Long parentId)
    {
        List<SysMenuEntity> returnList = new ArrayList<SysMenuEntity>();
        for (Iterator<SysMenuEntity> iterator = list.iterator(); iterator.hasNext();)
        {
        	SysMenuEntity t = (SysMenuEntity) iterator.next();
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() .equals( parentId))
            {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }
    
    
    /**
     * 递归列表
     * 
     * @param list
     * @param t
     */
    private void recursionFn(List<SysMenuEntity> list, SysMenuEntity t)
    {
        // 得到子节点列表
        List<SysMenuEntity> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenuEntity tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }
    
    
    /**
     * 得到子节点列表
     */
    private List<SysMenuEntity> getChildList(List<SysMenuEntity> list, SysMenuEntity t)
    {
        List<SysMenuEntity> tlist = new ArrayList<SysMenuEntity>();
        Iterator<SysMenuEntity> it = list.iterator();
        while (it.hasNext())
        {
        	SysMenuEntity n = (SysMenuEntity) it.next();
            if (n.getParentId() == t.getMenuId())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }
    
    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenuEntity> list, SysMenuEntity t)
    {
        return getChildList(list, t).size() > 0 ? true : false;
    }

	@Override
	public List<TreeSelect> buildMenuTreeSelect(List<SysMenuEntity> menuList) {
		List<SysMenuEntity>  menuTrees =  buildMenuTree(menuList);
		 return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
	}
    
	 /**
     * 构建前端所需要树结构
     * 
     * @param menus 菜单列表
     * @return 树结构列表
     */
    public List<SysMenuEntity> buildMenuTree(List<SysMenuEntity> menus)
    {
        List<SysMenuEntity> returnList = new ArrayList<SysMenuEntity>();
        List<Long> tempList = new ArrayList<Long>();
        for (SysMenuEntity dept : menus)
        {
            tempList.add(dept.getMenuId());
        }
        for (Iterator<SysMenuEntity> iterator = menus.iterator(); iterator.hasNext();)
        {
        	SysMenuEntity menu = (SysMenuEntity) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(menu.getParentId()))
            {
                recursionFn(menus, menu);
                returnList.add(menu);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = menus;
        }
        return returnList;
    }
   
}